<template>
  <div class="charts" :style="`width:${width}px;`">
    <canvas id="canvas"></canvas>
  </div>
</template>
<script>
export default {
  props: {
    width: {//盒子宽度
      type: Number,
      default: 500,//px
    },
    canvasHeight: {//盒子高度
      type: Number,
      default: 500,//px
    },
    titleWidth: {//标题宽度
      type: Number,
      default: 100,//px
    },
    parentTitleWidth: {//标题宽度
      type: Number,
      default: 100,//px
    },
    // 起始时间
    createTime: {
      type: String,
      default: '2023-04-08 11:10:05',//px
    },
    // 小时数
    hour: {
      type: Number,
      default: 5,
    },
  },
  data() {
    return {
      animationTime: 30,//动画时间
      ctx: null,
      startX: 0,
      vitalSignData: [
        {
          minValue: 200,
          maxValue: 300,
          normalColor: '#3c9cff',
          abnormalColor: '#e04040',
          tag: '',
          values: [175, 190, 400, 300, 400, 500, 150, 240, 350, 250, 260, 270, 280, 250]
        },

        // {
        //   minValue: 100,
        //   maxValue: 300,
        //   normalColor: '#3c9cff',
        //   abnormalColor: '#f9ae3d',
        //   tag: '',
        //   values: [345, 415, 450, 600, 489, 500, 469, 869, 335, 690, 495, 445]
        // },
        // {
        //   minValue: 30,
        //   maxValue: 50,
        //   normalColor: '#3c9cff',
        //   abnormalColor: '#f9ae3d',
        //   tag: '',
        //   values: [45, 60, 20, 45, 20, 45, 0, 45, 60, 0, 45]
        // }, {
        //   minValue: 100,
        //   maxValue: 200,
        //   normalColor: '#3c9cff',
        //   abnormalColor: '#f9ae3d',
        //   tag: '',
        //   values: [15, 133, 99, 300, 99, 99, 156, 99, 93, 77, 95]
        // },
      ],	//坐标轴坐标
      // point: [[0, 200], [150, 230], [200, 190], [250, 240], [300, 300], [350, 270], [400, 500], [450, 400], [500, 100]],	//点坐标
    }
  },
  mounted() {
    let canvas = document.getElementById("canvas");
    canvas.width = this.width
    canvas.height = this.canvasHeight
    this.ctx = canvas.getContext('2d');
    // 初始化
    this.initCharts()
  },
  watch: {

  },
  methods: {
    async initCharts() {
      // this.startX = this.titleWidth + this.parentTitleWidth
      // 绘制边框
      this.creat();
      // 绘制数线
      await this.insert();
      // 绘制完边框在绘制坐标  否则会造成颜色冲突
      setTimeout(() => {
        this.drawLines()
      }, this.animationTime * this.hour);
    },
    // 绘制折线
    drawLines() {
      // let color = ['#3c9cff', '#f9ae3d', '#5ac725', '#f56c6c', '#909399']
      for (let index = 0; index < this.vitalSignData.length; index++) {
        setTimeout(() => {
          this.drawLine(this.vitalSignData[index])
        }, this.animationTime * index);
      }
    },
    drawLineSegment(x1, y1, x2, y2, color) {
      this.ctx.beginPath();
      this.ctx.lineWidth = 2;
      this.ctx.shadowBlur = 5;
      this.ctx.strokeStyle = color;
      this.ctx.moveTo(x1, this.canvasHeight - y1);
      this.ctx.lineTo(x2, this.canvasHeight - y2);
      this.ctx.stroke();

    },
    drawLine(data) {
      // 以下最小值最大值含义指 正常范围允许的最小值和最大值
      let cell = this.width / this.hour;//平均吗每个x的宽度
      // 没有数据直接退出
      if (data.values.length <= 0) {
        return
      }
      // this.drawLineSegment(0, data.minValue, this.width, data.minValue, data.abnormalColor)
      // this.drawLineSegment(0, data.maxValue, this.width, data.maxValue, data.abnormalColor)

      // 第一个点
      // 绘制折现路径
      for (let i = 1; i < data.values.length; i++) {
        // console.log("i:", i);
        // console.log("value:", data.values[i])
        // 原点坐标
        let originalX = cell * (i - 1);
        let originalY = data.values[i - 1]

        // 目的坐标
        let destX = cell * (i);
        let destY = data.values[i]

        // 计算斜率
        let gradient = (destY - originalY) / (destX - originalX)

        // 斜率为正数
        if (gradient > 0) {
          // 斜截法 斜率 k=(y2-y1)/(x2-x1)   直线方程 y - y1 = k(x - x1)

          if (destY > data.maxValue) {
            // 如果目标点大于最大阈值
            // 增加最大值点
            let maxX = (data.maxValue - originalY) / gradient + originalX;
            let maxY = data.maxValue;

            if (originalY >= data.maxValue) {
              // 如果起始点同时大于最大阈值 结果为一段 非正常线

              // console.log(destX, destY);
              this.drawLineSegment(originalX, originalY, destX, destY, data.abnormalColor)
            } else if (originalY >= data.minValue) {
              // 如果起始点为正常值,则结果为两段

              // 起始点到最大值的正常线段
              // console.log(maxX, maxY);
              this.drawLineSegment(originalX, originalY, maxX, maxY, data.normalColor)

              // 最大值到目标点的异常线段
              // console.log(destX, destY);
              this.drawLineSegment(maxX, maxY, destX, destY, data.abnormalColor)
            } else {
              // 否则起始点小于正常点,则结果为三段
              let minX = (data.minValue - originalY) / gradient + originalX;
              let minY = data.minValue;

              // 起始点到最小值的非正常线段
              // console.log(minX, minY);

              this.drawLineSegment(originalX, originalY, minX, minY, data.abnormalColor)

              // 最小值到最大值的正常线段
              // console.log(maxX, maxY);
              this.drawLineSegment(minX, minY, maxX, maxY, data.normalColor)


              // 最大值到目标值的非正常线段
              // console.log(destX, destY);
              this.drawLineSegment(maxX, maxY, destX, destY, data.abnormalColor)
            }
          } else if (destY >= data.minValue) {
            // 如果目标点为正常值
            if (originalY >= data.minValue) {
              // 如果起始点为正常值 结果为一段
              // console.log(destX, destY);

              this.drawLineSegment(originalX, originalY, destX, destY, data.normalColor)
            } else {
              // 起始点小于正常值,结果为两段
              let minX = (data.minValue - originalY) / gradient + originalX;
              let minY = data.minValue;

              // 起始点到正常值的非正常线段
              // console.log(minX, minY);

              this.drawLineSegment(originalX, originalY, minX, minY, data.abnormalColor)

              // 最小值到目标值的正常线段
              // console.log(destX, destY);
              this.drawLineSegment(minX, minY, destX, destY, data.normalColor)
            }

          } else {
            // 否则目标值小于最小值 则结果为一段非正常线段
            // console.log(destX, destY);

            this.drawLineSegment(originalX, originalY, destX, destY, data.abnormalColor)
          }
        } else if (gradient === 0) {
          // console.log(destX, destY);

          // 斜率为0, 如果值小于最小值或者大于最大值,则非正常 否则正常线段
          if (originalY < data.minValue || originalY > data.maxValue) {
            this.drawLineSegment(originalX, originalY, destX, destY, data.abnormalColor);
          } else {
            this.drawLineSegment(originalX, originalY, destX, destY, data.normalColor);
          }
        } else {
          // 否则 斜率为负
          // 斜截法 斜率 k=(y2-y1)/(x2-x1)   直线方程 y - y1 = k(x - x1)
          if (originalY > data.maxValue) {
            // 如果起始点大于最大阈值
            // 增加最大值点
            let maxX = (data.maxValue - destY) / gradient + destX;
            let maxY = data.maxValue;

            if (destY >= data.maxValue) {
              // 如果目标点同时大于最大阈值 结果为一段 非正常线
              // console.log(destX, destY);
              this.drawLineSegment(originalX, originalY, destX, destY, data.abnormalColor);
            } else if (destY >= data.minValue) {
              // 如果目标点为正常值,则结果为两段

              // 起始点到最大值的非正常线段
              // console.log(maxX, maxY);
              this.drawLineSegment(originalX, originalY, maxX, maxY, data.abnormalColor);

              // 最大值到目标点的正常线段
              // console.log(destX, destY);
              this.drawLineSegment(maxX, maxY, destX, destY, data.normalColor);
            } else {
              // 否则目标点小于正常点,则结果为三段
              let minX = (data.minValue - destY) / gradient + destX;
              let minY = data.minValue;

              // 起始点到最大值的非正常线段
              // console.log(maxX, maxY);

              this.drawLineSegment(originalX, originalY, maxX, maxY, data.abnormalColor);

              // 最大值到最小值的正常线段
              // console.log(minX, minY);

              this.drawLineSegment(maxX, maxY, minX, minY, data.normalColor);

              // 最小值到目标值的非正常线段
              // console.log(destX, destY);

              this.drawLineSegment(minX, minY, destX, destY, data.abnormalColor);
            }

          } else if (originalY >= data.minValue) {
            // 如果起始点为正常值
            if (destY >= data.minValue) {
              // 如果目标点为正常值 结果为一段
              // console.log(destX, destY);

              this.drawLineSegment(originalX, originalY, destX, destY, data.abnormalColor);
            } else {
              // 目标点小于正常值,结果为两段
              let minX = (data.minValue - destY) / gradient + destX;
              let minY = data.minValue;

              // 起始点到最小值的正常线段
              // console.log(minX, minY);

              this.drawLineSegment(originalX, originalY, minX, minY, data.normalColor);

              // 最小值到目标值的非正常线段
              // console.log(destX, destY);
              this.drawLineSegment(minX, minY, destX, destY, data.abnormalColor);

            }
          } else {
            // 否则起始点小于最小值 则结果为一段非正常线段
            // console.log(destX, destY);

            this.drawLineSegment(originalX, originalY, destX, destY, data.abnormalColor);
          }
        }
      }

      this.ctx.restore();
    },
    // 绘制坐标  竖线
    insert() {
      // 绘制纵向列表
      let x = this.width / this.hour;//平均吗每个x的宽度
      let y = this.canvasHeight
      // 绘制y轴坐标线
      let i = 1
      let tmo = setInterval(() => {
        if (i === this.hour) {
          clearInterval(tmo)
        }
        this.ctx.beginPath();
        this.ctx.moveTo(x * i, 0);
        this.ctx.lineTo(x * i, y);
        this.ctx.closePath();
        this.ctx.strokeStyle = "#31C2AF";
        this.ctx.stroke();
        this.ctx.fillText(i, x * i, y);
        i++
      }, this.animationTime);
    },
    // 绘制边框
    creat() {
      this.ctx.beginPath();
      // 起始点
      this.ctx.moveTo(0, 0);
      // 左
      this.ctx.lineTo(0, this.canvasHeight);
      // 下
      this.ctx.lineTo(this.width, this.canvasHeight);
      // 右
      this.ctx.lineTo(this.width, 0);
      // 结束 闭合
      this.ctx.closePath();
      this.ctx.strokeStyle = "#31C2AF";
      this.ctx.stroke();
    }
  }
}
</script>
<style scoped lang="scss"></style>
